<template><div><h2 id="数据填充" tabindex="-1"><a class="header-anchor" href="#数据填充"><span>数据填充</span></a></h2>
<p>Laravel 6 中文文档 /</p>
<p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="数据库-填充" tabindex="-1"><a class="header-anchor" href="#数据库-填充"><span>数据库：填充</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#writing-seeders">编写 Seeders</a>
<ul>
<li><a href="#using-model-factories">使用模型工厂</a></li>
<li><a href="#calling-additional-seeders">调用其他 Seeders</a></li>
</ul>
</li>
<li><a href="#running-seeders">运行 Seeders</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>Laravel 包含一个填充类可以为你的数据库填充测试数据，所有的填充类都放在 <code v-pre>database/seeds</code> 目录下。你可以随意为填充类命名，但是更建议您遵守类似 <code v-pre>UsersTableSeeder</code> 的命名规范。通常， Laravel 默认定义了一个 <code v-pre>DatabaseSeeder</code> 类。通过这个类，你可以用 <code v-pre>call</code> 方法来运行其它的 seed 类从而控制数据填充的顺序。</p>
<h2 id="编写-seeders" tabindex="-1"><a class="header-anchor" href="#编写-seeders"><span>编写 Seeders</span></a></h2>
<p>运行 <a href="https://learnku.com/docs/laravel/6.x/artisan" target="_blank" rel="noopener noreferrer">Artisan 命令</a> <code v-pre>make:seeder</code> 生成 Seeder，框架生成的 seeders 都放在 <code v-pre>database/seeds</code> 目录下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan make<span class="token punctuation">:</span>seeder UsersTableSeeder</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>seeder 类只包含一个默认方法：<code v-pre>run</code> 。这个方法会在执行 <code v-pre>db:seed</code> 这个 <a href="https://learnku.com/docs/laravel/6.x/artisan" target="_blank" rel="noopener noreferrer">Artisan 命令</a> 时被调用。在 <code v-pre>run</code> 方法里你可以根据需要在数据库中插入数据。你也可以用 <a href="https://learnku.com/docs/laravel/6.x/queries" target="_blank" rel="noopener noreferrer">查询构造器</a> 或 <a href="https://learnku.com/docs/laravel/6.x/database-testing#writing-factories" target="_blank" rel="noopener noreferrer">Eloquent 模型工厂</a> 来手动插入数据。</p>
<blockquote>
<p>Tip：使用数据填充时会自动禁用 <a href="https://learnku.com/docs/laravel/6.x/eloquent#mass-assignment" target="_blank" rel="noopener noreferrer">批量赋值保护</a> 。</p>
</blockquote>
<p>如下所示，在默认的 <code v-pre>DatabaseSeeder</code> 类中的 <code v-pre>run</code> 方法中添加一条数据插入语句：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Str</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Seeder</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">DatabaseSeeder</span> <span class="token keyword">extends</span> <span class="token class-name">Seeder</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * Run the database seeds.</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token class-name static-context">Str</span><span class="token operator">::</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token class-name static-context">Str</span><span class="token operator">::</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token operator">.</span><span class="token string single-quoted-string">'@gmail.com'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token function">bcrypt</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Tip：你在 <code v-pre>run</code> 的方法签名中可以用类型来约束你需要的依赖。它们会被 Laravel <a href="https://learnku.com/docs/laravel/6.x/container" target="_blank" rel="noopener noreferrer">服务容器</a> 自动解析。</p>
</blockquote>
<h3 id="使用模型工厂" tabindex="-1"><a class="header-anchor" href="#使用模型工厂"><span>使用模型工厂</span></a></h3>
<p>手动为每个模型填充指定属性很麻烦，你可以使用 <a href="https://learnku.com/docs/laravel/6.x/database-testing#writing-factories" target="_blank" rel="noopener noreferrer">model 工厂</a> 轻松地生成大量数据库数据。首先，阅读 <a href="https://learnku.com/docs/laravel/6.x/database-testing#writing-factories" target="_blank" rel="noopener noreferrer">model 工厂文档</a> 来学习如何定义工厂文件，一旦定义好了你的工厂文件，然后就可以使用 <code v-pre>factory</code> 这个辅助函数来向数据库中插入数据。</p>
<p>例如，创建 50 个用户并为每个用户创建关联：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Run the database seeds.</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">each</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">posts</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">save</span><span class="token punctuation">(</span><span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="调用其它-seeders" tabindex="-1"><a class="header-anchor" href="#调用其它-seeders"><span>调用其它 Seeders</span></a></h3>
<p>在 <code v-pre>DatabaseSeeder</code> 类中，你可以使用 <code v-pre>call</code> 方法来运行其它的 seed 类。使用 <code v-pre>call</code> 方法可以将数据填充拆分成多个文件，这样就不会使单个 seeder 变得非常大。只需简单传递要运行的 seeder 类名称即可：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Run the database seeds.</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">UsersTableSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token class-name static-context">PostsTableSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token class-name static-context">CommentsTableSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="运行-seeders" tabindex="-1"><a class="header-anchor" href="#运行-seeders"><span>运行 Seeders</span></a></h2>
<p>完成 seeder 类的编写之后，你可能需要使用 <code v-pre>dump-autoload</code> 命令重新生成 Composer 的自动加载器：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">composer dump<span class="token operator">-</span>autoload</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>现在你可以使用 Artisan 命令 <code v-pre>db:seed</code> 来填充数据库了。默认情况下， <code v-pre>db:seed</code> 命令将运行 <code v-pre>DatabaseSeeder</code> 类，这个类可以用来调用其它 Seed 类。不过，你也可以使用 <code v-pre>--class</code> 选项来指定一个特定的 seeder 类：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan db<span class="token punctuation">:</span>seed</span>
<span class="line"></span>
<span class="line">php artisan db<span class="token punctuation">:</span>seed <span class="token operator">--</span><span class="token keyword">class</span><span class="token operator">=</span>UsersTableSeeder</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以用 <code v-pre>migrate:refresh</code> 这个命令来填充数据库，该命令会回滚并重新运行所有迁移。这个命令可以用来重建数据库：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan migrate<span class="token punctuation">:</span>refresh <span class="token operator">--</span>seed</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="在生产环境中强制使用" tabindex="-1"><a class="header-anchor" href="#在生产环境中强制使用"><span>在生产环境中强制使用</span></a></h4>
<p>一些填充操作可能会导致原有数据的更新或丢失。为了保护生产环境数据库的数据，在运行填充命令前会进行确认。可以添加 <code v-pre>--force</code>选项来强制运行填充命令:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan db<span class="token punctuation">:</span>seed <span class="token operator">--</span>force</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/6.x/seeding/5174" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/6.x/see...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/6.x/seeding/5174" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/6.x/see...</a></p>
</blockquote>
</div></template>


